home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / grapdrvs / os2drvs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-02  |  26.6 KB  |  864 lines

  1. /*****************************************************************************
  2. *   An OS2 2.x driver.                                 *
  3. *                                         *
  4. * Written by:  Gershon Elber                 Ver 0.1, October 1993.  *
  5. *****************************************************************************/
  6.  
  7. #include <stdio.h>
  8.  
  9. #define INCL_WINSTDFILE
  10. #define INCL_WININPUT
  11. #define INCL_WINFRAMEMGR
  12. #define INCL_WINMENUS
  13. #define INCL_DOSPROCESS
  14. #include <os2.h>
  15.  
  16. #include "irit_sm.h"
  17. #include "genmat.h"
  18. #include "iritprsr.h"
  19. #include "allocate.h"
  20. #include "attribut.h"
  21. #include "ip_cnvrt.h"
  22. #include "cagd_lib.h"
  23. #include "iritgrap.h"
  24. #include "os2drvs.h"
  25. #include "irit_soc.h"
  26.  
  27. #define ID_VIEW        1
  28. #define ID_TRANS    2
  29.  
  30. #define DEFAULT_TRANS_WIDTH    200
  31. #define DEFAULT_TRANS_HEIGHT    500
  32. #define DEFAULT_VIEW_WIDTH    400
  33. #define DEFAULT_VIEW_HEIGHT    400
  34.                                    
  35. #define ARGCV_LINE_LEN    1000
  36. #define ARGCV_MAX_WORDS    100
  37.  
  38. #define RGB_COLOR(R, G, B)    (((R) << 16) + ((G) << 8) + (B))
  39. #define GPI_MOVE(X, Y)    { POINTL Pt; Pt.x = X; Pt.y = Y; GpiMove(hps, &Pt); }
  40. #define GPI_LINE(X, Y)    { POINTL Pt; Pt.x = X; Pt.y = Y; GpiLine(hps, &Pt); }
  41. #define GPI_CHAR_STR_AT(Str, X, Y) { POINTL Pt; int l = strlen(Str); \
  42.                      Pt.x = X - cxChar * (l + 1) / 2; \
  43.                      Pt.y = Y - cyChar / 3; \
  44.                      GpiCharStringAt(hps, &Pt, l, Str); }
  45. #define OS2_MAP_X_COORD(x) ((int) (ViewWidth2 + x * ViewWidth2))
  46. #define OS2_MAP_Y_COORD(y) ((int) (ViewHeight2 + y * ViewWidth2))
  47.  
  48. #define WIN_CHECK_MENU(Item, Val)    WinSendMsg(hwndMenu, MM_SETITEMATTR, \
  49.                            MPFROM2SHORT(Item, TRUE), \
  50.                            MPFROM2SHORT(MIA_CHECKED, \
  51.                                 (Val)));
  52.  
  53. /* Interactive menu setup structure: */
  54. #define INTERACT_NUM_OF_STRINGS        3
  55. #define INTERACT_NUM_OF_SUB_WNDWS    15
  56. #define INTERACT_SUB_WINDOW_WIDTH  0.8         /* Relative to window size. */
  57. #define INTERACT_SUB_WINDOW_HEIGHT 0.04
  58.  
  59. typedef struct InteractString {
  60.     RealType X, Y;
  61.     int Color;
  62.     char *Str;
  63. } InteractString;
  64. typedef struct InteractSubWindow {
  65.     RealType X, Y;                       /* Center points. */
  66.     int Color;
  67.     IGGraphicEventType Event;
  68.     int TextInside; /* If TRUE, Str will be in window, otherwise left to it. */
  69.     char *Str;
  70. } InteractSubWindow;
  71. typedef struct InteractWindowStruct {     /* The interactive menu structures. */
  72.     /* Rotate, Translate, Scale strings: */
  73.     InteractString Strings[INTERACT_NUM_OF_STRINGS];
  74.     InteractSubWindow SubWindows[INTERACT_NUM_OF_SUB_WNDWS];
  75. } InteractWindowStruct;
  76.  
  77. /* Interactive mode menu set up structure is define below: */
  78. static InteractWindowStruct InteractMenu =
  79. {
  80.   {
  81.     { 0.5, 0.76, IG_IRIT_RED,   "Rotate" },
  82.     { 0.5, 0.56, IG_IRIT_GREEN, "Translate" },
  83.     { 0.5, 0.36, IG_IRIT_CYAN,  "Scale" },
  84.   },
  85.   {
  86.     { 0.5, 0.92, IG_IRIT_YELLOW, IG_EVENT_SCR_OBJ_TGL,    TRUE,  "Screen Coords." },
  87.     { 0.5, 0.84, IG_IRIT_BLUE,   IG_EVENT_PERS_ORTHO_TGL, TRUE,  "Perspective" },
  88.     { 0.5, 0.79, IG_IRIT_BLUE,   IG_EVENT_PERS_ORTHO_Z,   FALSE, "Z" },
  89.     { 0.5, 0.69, IG_IRIT_RED,    IG_EVENT_ROTATE_X,       FALSE, "X" },  /* Rot */
  90.     { 0.5, 0.64, IG_IRIT_RED,    IG_EVENT_ROTATE_Y,       FALSE, "Y" },
  91.     { 0.5, 0.59, IG_IRIT_RED,    IG_EVENT_ROTATE_Z,       FALSE, "Z" },
  92.     { 0.5, 0.49, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_X,    FALSE, "X" },/* Trans */
  93.     { 0.5, 0.44, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_Y,    FALSE, "Y" },
  94.     { 0.5, 0.39, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_Z,    FALSE, "Z" },
  95.     { 0.5, 0.29, IG_IRIT_CYAN,   IG_EVENT_SCALE,      FALSE, "" }, /* Scale */
  96.     { 0.5, 0.21, IG_IRIT_YELLOW, IG_EVENT_DEPTH_CUE,      TRUE,  "Depth Cue" },
  97.     { 0.5, 0.16, IG_IRIT_YELLOW, IG_EVENT_SAVE_MATRIX,    TRUE,  "Save Matrix" },
  98.     { 0.5, 0.12, IG_IRIT_YELLOW, IG_EVENT_PUSH_MATRIX,    TRUE,  "Push Matrix" },
  99.     { 0.5, 0.08, IG_IRIT_YELLOW, IG_EVENT_POP_MATRIX,     TRUE,  "Pop Matrix" },
  100.     { 0.5, 0.03, IG_IRIT_WHITE,  IG_EVENT_QUIT,              TRUE,  "Quit" },
  101.   }
  102. };
  103.  
  104. /* Colors to be used for viewed object (see also iritgrap.h):           */
  105. /* This colors are adjusted so as to give OS2 2.x a better chance at       */
  106. /* selecting these colors as solid.                       */
  107. static short Colors[IG_MAX_COLOR + 1][3] =
  108. {
  109.     { 0,   0,   0   },  /* 0. BLACK */
  110.     { 0,   0,   255 },  /* 1. BLUE */
  111.     { 0,   255, 0   },  /* 2. GREEN */
  112.     { 0,   255, 255 },  /* 3. CYAN */
  113.     { 255, 0,   0   },  /* 4. RED */
  114.     { 255, 0,   255 },  /* 5. MAGENTA */
  115.     { 127, 127, 0   },  /* 6. BROWN */
  116.     { 127, 127, 127 },  /* 7. LIGHTGREY */
  117.     { 63,  63,  63  },  /* 8. DARKGRAY */
  118.     { 63,  63,  255 },  /* 9. LIGHTBLUE */
  119.     { 63,  255, 63  },  /* 10. LIGHTGREEN */
  120.     { 63,  255, 255 },  /* 11. LIGHTCYAN */
  121.     { 255, 63,  63  },  /* 12. LIGHTRED */
  122.     { 255, 63,  255 },  /* 13. LIGHTMAGENTA */
  123.     { 255, 255, 63  },  /* 14. YELLOW */
  124.     { 255, 255, 255 }   /* 15. WHITE */
  125. };
  126.  
  127. static unsigned int
  128.     TransWidth = DEFAULT_TRANS_WIDTH,
  129.     TransHeight = DEFAULT_TRANS_HEIGHT,
  130.     TransWidth2 = DEFAULT_TRANS_WIDTH / 2,
  131.     ViewWidth2 = DEFAULT_VIEW_WIDTH / 2,
  132.     ViewHeight2 = DEFAULT_VIEW_HEIGHT / 2;
  133.  
  134. static LONG CrntColorLowIntensity, CrntColorHighIntensity,
  135.     ColorsLowIntensity[IG_MAX_COLOR + 1], ColorsHighIntensity[IG_MAX_COLOR + 1];
  136. static HPS
  137.     CurrentHps = 0;
  138. static HWND
  139.     hwndMenu = 0,
  140.     hwndFrame = 0,
  141.     hwndClient = 0,
  142.     hwndViewFrame = 0,
  143.     hwndTransFrame = 0;
  144.  
  145. static void GetInputFromSocket(void *Data);
  146. static MRESULT TransWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  147. static MRESULT ViewWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  148. static MRESULT ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  149. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor, int X, int Y);
  150. static void RedrawViewWindow(HWND hwnd);
  151. static void RedrawTransformationWindow(HWND hwnd);
  152. static void SetColorIndex(int c);
  153. static void SetColorRGB(int Color[3]);
  154.  
  155. /****************************************************************************
  156. * Pop up all windows, read input and display.                    *
  157. ****************************************************************************/
  158. void main(int argc, char **argv)
  159. {
  160.     static ULONG flFrameFlags;
  161.     static char
  162.     *szClientClass = "os2iritdrv.Client",
  163.     *szViewClass = "os2iritdrv.View",
  164.     *szTransClass = "os2iritdrv.Trans";
  165.     char
  166.     *IritPos = getenv("IRIT_POS");
  167.     int i,
  168.     Xmin = 190,
  169.     Ymin = 190,
  170.     Width = 600,
  171.     Height = 400;
  172.     QMSG qMsg;
  173.     HPS hps;
  174.     HAB hab;
  175.     HMQ hmq;
  176.     RECTL rcl, DeskTopRcl;
  177.  
  178.     IGConfigureGlobals("os2drvs", argc, argv);
  179.     if (getenv("IRIT_DISPLAY_S") != NULL)
  180.     IGGlblStandAlone = FALSE;
  181.  
  182.     if (IritPos)
  183.     sscanf(IritPos, "%d %d %d %d", &Xmin, &Ymin, &Width, &Height);
  184.  
  185.     hab = WinInitialize(0);
  186.     hmq = WinCreateMsgQueue(hab, 0);
  187.  
  188.     WinRegisterClass(hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0L);
  189.     WinRegisterClass(hab, szViewClass,   ViewWndProc,   CS_SIZEREDRAW, 0L);
  190.     WinRegisterClass(hab, szTransClass,  TransWndProc,  CS_SIZEREDRAW, 0L);
  191.  
  192.     flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU  |
  193.                    FCF_SIZEBORDER    | FCF_MINMAX   |
  194.                    FCF_SHELLPOSITION | FCF_TASKLIST |
  195.            FCF_MENU;
  196.  
  197.     hwndFrame = WinCreateStdWindow(
  198.                     HWND_DESKTOP,
  199.                     0,
  200.                     &flFrameFlags,
  201.                     szClientClass,
  202.                     NULL,
  203.                     0L,
  204.                     0,
  205.                     ID_OS2DRVS,
  206.                     &hwndClient);
  207.  
  208.     WinQueryWindowRect(HWND_DESKTOP, &DeskTopRcl);
  209.  
  210.     if (DeskTopRcl.yTop < Ymin + Height)   /* Make sure top side is visible. */
  211.     Ymin = DeskTopRcl.yTop - Height;
  212.  
  213.     WinSetWindowPos(hwndFrame, HWND_TOP, Xmin, Ymin, Width, Height,
  214.                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER);
  215.  
  216.     WinQueryWindowRect(hwndClient, &rcl);
  217.     flFrameFlags &= (~FCF_TASKLIST & ~FCF_MENU);
  218.  
  219.     hwndViewFrame = WinCreateWindow(
  220.             hwndClient,
  221.             szViewClass,
  222.             NULL,
  223.             WS_VISIBLE,
  224.             5,
  225.             5,
  226.             (SHORT) ((rcl.xRight * 4) / 5 - 10),
  227.             (SHORT) (rcl.yTop - 10),
  228.             hwndClient,
  229.             HWND_BOTTOM,
  230.             ID_VIEW,
  231.             NULL,
  232.             NULL);
  233.  
  234.     hwndTransFrame = WinCreateWindow(
  235.             hwndClient,
  236.             szTransClass,
  237.             NULL,
  238.             WS_VISIBLE,
  239.             (SHORT) ((rcl.xRight * 4) / 5),
  240.             5,
  241.             (SHORT) (rcl.xRight / 5 - 5),
  242.             (SHORT) (rcl.yTop - 10),
  243.             hwndClient,
  244.             HWND_BOTTOM,
  245.             ID_TRANS,
  246.             NULL,
  247.             NULL);
  248.  
  249.     if (hwndViewFrame == 0 || hwndTransFrame == 0) {
  250.         DosBeep(1000, 100);
  251.         exit(1);
  252.     }
  253.  
  254.     /* Preallocate the colors that will be used frequently. */
  255.     hps = WinBeginPaint(hwndFrame, NULL, NULL);
  256.     for (i = 0; i <= IG_MAX_COLOR; i++) {
  257.     ColorsHighIntensity[i] =
  258.         GpiQueryColorIndex(hps, 0L,
  259.         RGB_COLOR(Colors[i][0], Colors[i][1], Colors[i][2]));
  260.     ColorsLowIntensity[i] =
  261.         GpiQueryColorIndex(hps, 0L,
  262.         RGB_COLOR(Colors[i][0] / 2,
  263.               Colors[i][1] / 2,
  264.               Colors[i][2] / 2));
  265.     }
  266.     WinEndPaint(hps);
  267.  
  268.     /* Set up the reading socket as a secondary threat. */
  269.     if (!IGGlblStandAlone) {
  270.     if (_beginthread(GetInputFromSocket, NULL, 128 * 1024, NULL) == -1) {
  271.         WinMessageBox(HWND_DESKTOP, hwndFrame, "Failed to start thread\n",
  272.               NULL, 0, MB_OK);
  273.         exit(1);
  274.     }
  275.     }
  276.  
  277.     while (WinGetMsg(hab, &qMsg, 0L, 0, 0))
  278.     WinDispatchMsg(hab, &qMsg);
  279.  
  280.     WinDestroyWindow(hwndFrame);
  281.     WinDestroyMsgQueue(hmq);
  282.     WinTerminate(hab);
  283. }
  284.  
  285. /*****************************************************************************
  286. * Updates the toggles in the menu.                         *
  287. *****************************************************************************/
  288. void IGCreateStateMenu(void)
  289. {
  290.     WIN_CHECK_MENU(IDM_TGLS_SCREEN, 
  291.            IGGlblTransformMode == IG_TRANS_SCREEN ? MIA_CHECKED : 0);
  292.     WIN_CHECK_MENU(IDM_TGLS_PERSP,
  293.            IGGlblViewMode == IG_VIEW_PERSPECTIVE ? MIA_CHECKED : 0);
  294.     WIN_CHECK_MENU(IDM_TGLS_DEPTH_CUE, IGGlblDepthCue ? MIA_CHECKED : 0);
  295.     WIN_CHECK_MENU(IDM_TGLS_INTERNAL, IGGlblDrawInternal ? MIA_CHECKED : 0);
  296.     WIN_CHECK_MENU(IDM_TGLS_VRTX_NRML, IGGlblDrawVNormal ? MIA_CHECKED : 0);
  297.     WIN_CHECK_MENU(IDM_TGLS_POLY_NRML, IGGlblDrawPNormal ? MIA_CHECKED : 0);
  298.     WIN_CHECK_MENU(IDM_TGLS_CTL_MESH, IGGlblDrawSurfaceMesh ? MIA_CHECKED : 0);
  299.     WIN_CHECK_MENU(IDM_TGLS_SRF_POLYS, IGGlblDrawSurfacePoly ? MIA_CHECKED : 0);
  300.     WIN_CHECK_MENU(IDM_TGLS_4_PER_FLAT, IGGlblFourPerFlat ? MIA_CHECKED : 0);
  301. }
  302.  
  303. /*****************************************************************************
  304. * A secondary threat that waits for input from socket.                 *
  305. *****************************************************************************/
  306. static void GetInputFromSocket(void *Data)
  307. {
  308.     SocClientCreateSocket();
  309.  
  310.     while (TRUE) {
  311.     if (IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
  312.         WinInvalidateRect(hwndViewFrame, NULL, FALSE);
  313.     }
  314. }
  315.  
  316. /****************************************************************************
  317. * Trans window drawing function.                        *
  318. ****************************************************************************/
  319. static MRESULT TransWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  320. {
  321.     static IGGraphicEventType
  322.     LastEvent = IG_EVENT_NONE;
  323.     static int
  324.     LastX = 0,
  325.     Button1Down = FALSE;
  326.     RealType ChangeFactor;
  327.     IGGraphicEventType Event;
  328.     int x, y;
  329.     
  330.     switch (msg) {
  331.         case WM_CREATE:
  332.         break;
  333.     case WM_BUTTON1UP:
  334.         Button1Down = FALSE;
  335.         break;
  336.     case WM_BUTTON1DOWN:
  337.         LastEvent = IG_EVENT_NONE;
  338.         x = SHORT1FROMMP(mp1);
  339.         y = SHORT2FROMMP(mp1);
  340.  
  341.         if ((Event = GetGraphicEvent(&ChangeFactor, x, y))
  342.                                != IG_EVENT_NONE) {
  343.         if (Event == IG_EVENT_QUIT) {
  344.             exit(0);           /* Not the nicest ways to quit. */
  345.         }
  346.         else {
  347.             if (IGProcessEvent(Event,
  348.                        ChangeFactor * IGGlblChangeFactor))
  349.                 WinInvalidateRect(hwndViewFrame, NULL, TRUE);
  350.  
  351.             /* Save the event in case drag operation is performed. */
  352.             LastEvent = Event;
  353.             LastX = x;
  354.         }
  355.         }
  356.         Button1Down = TRUE;
  357.         break;
  358.     case WM_MOUSEMOVE:
  359.         if (Button1Down && LastEvent != IG_EVENT_NONE) {
  360.         ChangeFactor = ((x = SHORT1FROMMP(mp1)) - ((RealType) LastX)) /
  361.                                    TransWidth2;
  362.         if (IGProcessEvent(LastEvent,
  363.                    ChangeFactor * IGGlblChangeFactor))
  364.             WinInvalidateRect(hwndViewFrame, NULL, TRUE);
  365.         LastX = x;
  366.         }
  367.         break;
  368.         case WM_PAINT:
  369.         RedrawTransformationWindow(hwnd);
  370.         break;
  371.         case WM_COMMAND:
  372.         break;
  373.     }
  374.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  375. }
  376.  
  377. /****************************************************************************
  378. * View window drawing function.                            *
  379. ****************************************************************************/
  380. static MRESULT ViewWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  381. {
  382.     switch (msg) {
  383.         case WM_PAINT:
  384.         RedrawViewWindow(hwnd);
  385.         break;
  386.         case WM_COMMAND:
  387.             switch (SHORT1FROMMP(mp1)) {
  388.             }
  389.             break;
  390.     }
  391.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  392. }
  393.  
  394. /****************************************************************************
  395. * Frame window drawing function.                        *
  396. ****************************************************************************/
  397. static MRESULT ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  398. {
  399.     POINTL Pt;
  400.     RECTL rcl;
  401.     HPS hps;
  402.     int Refresh;
  403.     FILEDLG fild;
  404.     static int
  405.     Resized = FALSE;
  406.  
  407.     switch (msg) {
  408.     case WM_CREATE:
  409.         hwndMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
  410.                        FID_MENU);
  411.         break;
  412.         case WM_SIZE:
  413.         Resized = TRUE;
  414.         break;
  415.         case WM_PAINT:
  416.         hps = WinBeginPaint(hwnd, NULL, NULL);
  417.  
  418.         WinQueryWindowRect(hwnd, &rcl);
  419.         GpiSetColor(hps, CLR_WHITE);
  420.         Pt.x = Pt.y = 0;
  421.         GpiMove(hps, &Pt);
  422.         Pt.x = rcl.xRight;
  423.         Pt.y = rcl.yTop;
  424.         GpiBox(hps, DRO_OUTLINEFILL, &Pt, 0, 0);
  425.  
  426.         WinEndPaint(hps);
  427.  
  428.         if (Resized) {
  429.             Resized = FALSE;
  430.             
  431.             if (hwndViewFrame)
  432.             WinSetWindowPos(hwndViewFrame, HWND_BOTTOM, 5, 5,
  433.                     (SHORT) ((rcl.xRight * 4) / 5 - 10),
  434.                     (SHORT) (rcl.yTop - 10),
  435.                     SWP_SIZE | SWP_MOVE);
  436.         if (hwndTransFrame)
  437.             WinSetWindowPos(hwndTransFrame, HWND_BOTTOM,
  438.                     (SHORT) (rcl.xRight * 4 / 5), 5,
  439.                     (SHORT) (rcl.xRight / 5 - 5),
  440.                     (SHORT) (rcl.yTop - 10),
  441.                     SWP_SIZE | SWP_MOVE);
  442.         }
  443.             break;
  444.         case WM_COMMAND:
  445.         Refresh = FALSE;
  446.             switch (SHORT1FROMMP(mp1)) {
  447.         case IDM_FILE_SAVE:
  448.             IGSaveCurrentMat(IGGlblViewMode, NULL);
  449.             break;
  450.         case IDM_FILE_SAVE_AS:
  451.             memset(&fild, 0, sizeof(FILEDLG));
  452.             fild.cbSize = sizeof(FILEDLG);
  453.             fild.pszTitle = "Save View Matrix";
  454.             fild.pszOKButton = "Save";
  455.             fild.fl = FDS_OPEN_DIALOG | FDS_CENTER ;
  456.             WinFileDlg(HWND_DESKTOP, hwndClient, &fild);
  457.  
  458.             if (strlen(fild.szFullFile) > 0)
  459.             IGSaveCurrentMat(IGGlblViewMode, fild.szFullFile);
  460.             break;
  461.         case IDM_FILE_QUIT:
  462.             exit(0);
  463.             break;
  464.  
  465.         case IDM_MOUSE_MORE:
  466.             IGHandleState(IG_STATE_MORE_SENSITIVE, TRUE);
  467.             break;
  468.         case IDM_MOUSE_LESS:
  469.             IGHandleState(IG_STATE_LESS_SENSITIVE, TRUE);
  470.             break;
  471.  
  472.         case IDM_STATE_MORE_ISO:
  473.             Refresh = IGHandleState(IG_STATE_MORE_ISOLINES, TRUE);
  474.             break;
  475.         case IDM_STATE_LESS_ISO:
  476.             Refresh = IGHandleState(IG_STATE_LESS_ISOLINES, TRUE);
  477.             break;
  478.         case IDM_STATE_FINER_APPROX:
  479.             Refresh = IGHandleState(IG_STATE_FINER_APPROX, TRUE);
  480.             break;
  481.         case IDM_STATE_COARSER_APPROX:
  482.             Refresh = IGHandleState(IG_STATE_COARSER_APPROX, TRUE);
  483.             break;
  484.         case IDM_STATE_SHORTER_VEC:
  485.             Refresh = IGHandleState(IG_STATE_SHORTER_VECTORS, TRUE);
  486.             break;
  487.         case IDM_STATE_LONGER_VEC:
  488.             Refresh = IGHandleState(IG_STATE_LONGER_VECTORS, TRUE);
  489.             break;
  490.         case IDM_STATE_WIDE_LINES:
  491.             Refresh = IGHandleState(IG_STATE_WIDER_LINES, TRUE);
  492.             break;
  493.         case IDM_STATE_THIN_LINES:
  494.             Refresh = IGHandleState(IG_STATE_NARROW_LINES, TRUE);
  495.             break;
  496.  
  497.         case IDM_TGLS_SCREEN:
  498.             IGHandleState(IG_STATE_SCR_OBJ_TGL, TRUE);
  499.             break;
  500.         case IDM_TGLS_PERSP:
  501.             Refresh = IGHandleState(IG_STATE_PERS_ORTHO_TGL, TRUE);
  502.             break;
  503.         case IDM_TGLS_DEPTH_CUE:
  504.             Refresh = IGHandleState(IG_STATE_DEPTH_CUE, TRUE);
  505.             break;
  506.         case IDM_TGLS_INTERNAL:
  507.             Refresh = IGHandleState(IG_STATE_DRAW_INTERNAL, TRUE);
  508.             break;
  509.         case IDM_TGLS_VRTX_NRML:
  510.             Refresh = IGHandleState(IG_STATE_DRAW_VNORMAL, TRUE);
  511.             break;
  512.         case IDM_TGLS_POLY_NRML:
  513.             Refresh = IGHandleState(IG_STATE_DRAW_PNORMAL, TRUE);
  514.             break;
  515.         case IDM_TGLS_CTL_MESH:
  516.             Refresh = IGHandleState(IG_STATE_DRAW_SRF_MESH, TRUE);
  517.             break;
  518.         case IDM_TGLS_SRF_POLYS:
  519.             Refresh = IGHandleState(IG_STATE_DRAW_SRF_POLY, TRUE);
  520.             break;
  521.         case IDM_TGLS_4_PER_FLAT:
  522.             Refresh = IGHandleState(IG_STATE_FOUR_PER_FLAT, TRUE);
  523.             break;
  524.  
  525.         case IDM_VIEW_FRONT:
  526.             Refresh = IGHandleState(IG_STATE_VIEW_FRONT, TRUE);
  527.             break;
  528.         case IDM_VIEW_SIDE:
  529.             Refresh = IGHandleState(IG_STATE_VIEW_SIDE, TRUE);
  530.             break;
  531.         case IDM_VIEW_TOP:
  532.             Refresh = IGHandleState(IG_STATE_VIEW_TOP, TRUE);
  533.             break;
  534.         case IDM_VIEW_ISOMETRY:
  535.             Refresh = IGHandleState(IG_STATE_VIEW_ISOMETRY, TRUE);
  536.             break;
  537.             }
  538.         if (Refresh)
  539.         WinInvalidateRect(hwndViewFrame, NULL, FALSE);
  540.             break;
  541.     }
  542.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  543. }
  544.  
  545. /******************************************************************************
  546. * Get an XY location on the transformation window and computes the evnet.     *
  547. ******************************************************************************/
  548. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor, int X, int Y)
  549. {
  550.     int i;
  551.     IGGraphicEventType
  552.     RetVal = IG_EVENT_NONE;
  553.     RealType XPos, YPos;
  554.  
  555.     XPos = ((RealType) X) / TransWidth;
  556.     YPos = ((RealType) Y) / TransHeight;
  557.  
  558.     /* Make sure we are in bound in the X direction. */
  559.     if (XPos < (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0 ||
  560.         XPos > 1.0 - (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0)
  561.     return IG_EVENT_NONE;
  562.  
  563.     /* Now search the sub window the event occured in. */
  564.     for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
  565.         if (InteractMenu.SubWindows[i].Y <= YPos &&
  566.         InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT >=
  567.                                       YPos) {
  568.         RetVal = InteractMenu.SubWindows[i].Event;
  569.         break;
  570.     }
  571.     }
  572.  
  573.     /* Take care of special cases in which the window should be updated. */
  574.     switch (RetVal) {
  575.     case IG_EVENT_SCR_OBJ_TGL:
  576.         IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
  577.                              IG_TRANS_SCREEN :
  578.                              IG_TRANS_OBJECT;
  579.         WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  580.         IGCreateStateMenu();
  581.         break;
  582.     case IG_EVENT_PERS_ORTHO_TGL:
  583.         IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  584.                            IG_VIEW_ORTHOGRAPHIC :
  585.                            IG_VIEW_PERSPECTIVE;
  586.         WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  587.         IGCreateStateMenu();
  588.         break;
  589.     case IG_EVENT_DEPTH_CUE:
  590.         IGGlblDepthCue = !IGGlblDepthCue;
  591.         WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  592.         IGCreateStateMenu();
  593.         break;
  594.     default:
  595.         break;
  596.     }
  597.  
  598.     *ChangeFactor = (((RealType) X) - TransWidth2) / TransWidth2;
  599.  
  600.     return RetVal;
  601. }
  602.  
  603. /*****************************************************************************
  604. * Redraw the viewing window.                             *
  605. *****************************************************************************/
  606. static void RedrawViewWindow(HWND hwnd)
  607. {
  608.     RECTL rcl;
  609.     IPObjectStruct *PObj;
  610.  
  611.     switch (IGGlblViewMode) {         /* Update the current view. */
  612.     case IG_VIEW_ORTHOGRAPHIC:
  613.         GEN_COPY(IGGlblCrntViewMat, IritPrsrViewMat, sizeof(MatrixType));
  614.         break;
  615.     case IG_VIEW_PERSPECTIVE:
  616.         MatMultTwo4by4(IGGlblCrntViewMat, IritPrsrViewMat,
  617.                             IritPrsrPrspMat);
  618.         break;
  619.     }
  620.  
  621.     CurrentHps = WinBeginPaint(hwnd, NULL, NULL);
  622.     WinQueryWindowRect(hwnd, &rcl);
  623.     ViewWidth2 = rcl.xRight / 2;
  624.     ViewHeight2 = rcl.yTop / 2;
  625.     WinFillRect(CurrentHps, &rcl, CLR_BLUE);
  626.  
  627.     /* Slim chance that a race will oocur if the following test and set */
  628.     /* is done simultanuously. Should use semaphors probably.            */
  629.     while (IGGlblDisplayListIsUsed) {
  630.     IritSleep(10);
  631.     DosEnterCritSec();
  632.     if (!IGGlblDisplayListIsUsed) {
  633.         IGGlblDisplayListIsUsed = TRUE;
  634.         DosExitCritSec();
  635.         break;
  636.     }
  637.     DosExitCritSec();
  638.     }
  639.  
  640.     GpiSetLineWidthGeom(CurrentHps, IGGlblLineWidth);
  641.  
  642.     for (PObj = IGGlblDisplayList, IGGlblAbortKeyPressed = FALSE;
  643.      PObj != NULL && !IGGlblAbortKeyPressed;
  644.      PObj = PObj -> Pnext)
  645.     IGDrawObject(PObj);
  646.  
  647.     IGGlblDisplayListIsUsed = FALSE;
  648.  
  649.     WinEndPaint(CurrentHps);
  650.     CurrentHps = 0;
  651. }
  652.  
  653. /*****************************************************************************
  654. * Redraw the transformation window.                         *
  655. *****************************************************************************/
  656. static void RedrawTransformationWindow(HWND hwnd)
  657. {
  658.     int i, cxChar, cyChar,
  659.     SubTransWidth, SubTransHeight, SubTransPosX, SubTransPosY;
  660.     POINTL Pt;
  661.     RECTL rcl;
  662.     FONTMETRICS fm;
  663.     HPS hps = WinBeginPaint(hwnd, NULL, NULL);
  664.  
  665.     GpiQueryFontMetrics(WinGetPS(hwnd), (LONG) sizeof(fm), &fm);
  666.     cxChar = fm.lAveCharWidth;
  667.     cyChar = fm.lMaxBaselineExt;
  668.  
  669.     /* Make sure the menu is consistent with internatal data. */
  670.     InteractMenu.SubWindows[0].Str =
  671.     IGGlblTransformMode == IG_TRANS_OBJECT ? "Object Coords."
  672.                            : "Screen Coords.";
  673.     InteractMenu.SubWindows[1].Str =
  674.     IGGlblViewMode == IG_VIEW_PERSPECTIVE ? "Perspective"
  675.                           : "Orthographic";
  676.     InteractMenu.SubWindows[10].Str =
  677.     IGGlblDepthCue ? "Depth cue" : "No depth cue";
  678.         
  679.     WinQueryWindowRect(hwnd, &rcl);
  680.     TransWidth = rcl.xRight;
  681.     TransWidth2 = rcl.xRight / 2;
  682.     TransHeight = rcl.yTop;
  683.  
  684.     SubTransWidth = (int) (TransWidth * INTERACT_SUB_WINDOW_WIDTH);
  685.     SubTransHeight = (int) (TransHeight *
  686.                 INTERACT_SUB_WINDOW_HEIGHT);
  687.     SubTransPosX = (TransWidth - SubTransWidth) / 2;
  688.  
  689.     GpiSetColor(hps, CLR_BLACK);
  690.     Pt.x = Pt.y = 0;
  691.     GpiMove(hps, &Pt);
  692.     Pt.x = TransWidth;
  693.     Pt.y = TransHeight;
  694.     GpiBox(hps, DRO_OUTLINEFILL, &Pt, 0, 0);
  695.  
  696.     for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
  697.     GpiSetColor(hps, InteractMenu.SubWindows[i].Color);
  698.     SubTransPosY = (int) (TransHeight *
  699.                   InteractMenu.SubWindows[i].Y);
  700.     
  701.     GPI_MOVE(SubTransPosX, SubTransPosY);
  702.     GPI_LINE(SubTransPosX + SubTransWidth, SubTransPosY);
  703.     GPI_LINE(SubTransPosX + SubTransWidth,
  704.          SubTransPosY + SubTransHeight);
  705.     GPI_LINE(SubTransPosX, SubTransPosY + SubTransHeight);
  706.     GPI_LINE(SubTransPosX, SubTransPosY);
  707.     if (InteractMenu.SubWindows[i].TextInside) {
  708.         GPI_CHAR_STR_AT(InteractMenu.SubWindows[i].Str,
  709.                 TransWidth / 2,
  710.                 SubTransPosY + SubTransHeight / 2);
  711.     }
  712.     else {
  713.         GPI_CHAR_STR_AT(InteractMenu.SubWindows[i].Str,
  714.                 (TransWidth - SubTransWidth) / 3,
  715.                 SubTransPosY + SubTransHeight / 2);
  716.         GPI_MOVE(SubTransPosX + SubTransWidth / 2, SubTransPosY);
  717.         GPI_LINE(SubTransPosX + SubTransWidth / 2,
  718.              SubTransPosY + SubTransHeight);
  719.     }
  720.     }
  721.  
  722.     for (i = 0; i < INTERACT_NUM_OF_STRINGS; i++) {
  723.     GpiSetColor(hps, InteractMenu.Strings[i].Color);
  724.     GPI_CHAR_STR_AT(InteractMenu.Strings[i].Str,
  725.             (int) (InteractMenu.Strings[i].X * TransWidth),
  726.             (int) (InteractMenu.Strings[i].Y * TransHeight));
  727.     }
  728.  
  729.     WinEndPaint(hps);
  730. }
  731.  
  732. /****************************************************************************
  733. * Routine to move in 2D normalized (-1..1) view space.                *
  734. ****************************************************************************/
  735. void IGMoveTo2D(RealType X, RealType Y)
  736. {
  737.     POINTL Pt;
  738.  
  739.     Pt.x = OS2_MAP_X_COORD(X);
  740.     Pt.y = OS2_MAP_Y_COORD(Y);
  741.     GpiMove(CurrentHps, &Pt);
  742. }
  743.  
  744. /****************************************************************************
  745. * Routine to draw in 2D normalized (-1..1) view space.                *
  746. ****************************************************************************/
  747. void IGLineTo2D(RealType X, RealType Y)
  748. {
  749.     POINTL Pt;
  750.  
  751.     Pt.x = OS2_MAP_X_COORD(X);
  752.     Pt.y = OS2_MAP_Y_COORD(Y);
  753.     GpiLine(CurrentHps, &Pt);
  754. }
  755.  
  756. /****************************************************************************
  757. * Routine to set the intensity of a color (high or low).            *
  758. ****************************************************************************/
  759. void IGSetColorIntensity(int High)
  760. {
  761.     if (!CurrentHps)
  762.     return;
  763.     GpiSetColor(CurrentHps,
  764.         High ? CrntColorHighIntensity : CrntColorLowIntensity);
  765.  
  766.     IGGlblIntensityHighState = High;
  767. }
  768.  
  769. /****************************************************************************
  770. * Routine to set the color according to the given object's color.        *
  771. ****************************************************************************/
  772. void IGSetColorObj(IPObjectStruct *PObj)
  773. {
  774.     int c, Color[3];
  775.  
  776.     if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
  777.     SetColorRGB(Color);
  778.     }
  779.     else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
  780.     SetColorIndex(c);
  781.     }
  782.     else {
  783.     /* Use white as default color: */
  784.     SetColorIndex(IG_IRIT_WHITE);
  785.     }
  786. }
  787.  
  788. /****************************************************************************
  789. * Routine to set the color according to the given color index.            *
  790. ****************************************************************************/
  791. static void SetColorIndex(int color)
  792. {
  793.     if (color > IG_MAX_COLOR)
  794.     color = IG_IRIT_WHITE;
  795.  
  796.     CrntColorHighIntensity = ColorsHighIntensity[color];
  797.     CrntColorLowIntensity = ColorsLowIntensity[color];
  798.  
  799.     if (CurrentHps) {
  800.     GpiSetColor(CurrentHps, CrntColorHighIntensity);
  801. }
  802.  
  803.     IGGlblIntensityHighState = TRUE;
  804. }
  805.  
  806. /****************************************************************************
  807. * Routine to set the color according to the given RGB values.            *
  808. ****************************************************************************/
  809. static void SetColorRGB(int Color[3])
  810. {
  811.     if (!CurrentHps)
  812.     return;
  813.  
  814.     CrntColorHighIntensity =
  815.     GpiQueryColorIndex(CurrentHps, 0L,
  816.                RGB_COLOR(Color[0], Color[1], Color[2]));
  817.     CrntColorLowIntensity =
  818.     GpiQueryColorIndex(CurrentHps, 0L,
  819.                RGB_COLOR(Color[0] / 2, Color[1] / 2, Color[2] / 2));
  820.  
  821.     GpiSetColor(CurrentHps, CrntColorHighIntensity);
  822.  
  823.     IGGlblIntensityHighState = TRUE;
  824. }
  825.  
  826. /******************************************************************************
  827. * Handle the event of a pop up window.                          *
  828. ******************************************************************************/
  829. int IGHandleState(int State, int Refresh)
  830. {
  831.     int UpdateView = TRUE;
  832.  
  833.     switch (State) {
  834.     case IG_STATE_WIDER_LINES:
  835.         IGGlblLineWidth *= 2;
  836.         break;
  837.     case IG_STATE_NARROW_LINES:
  838.         IGGlblLineWidth /= 2;
  839.         if (IGGlblLineWidth < 1)
  840.         IGGlblLineWidth = 1;
  841.         break;
  842.         case IG_STATE_SCR_OBJ_TGL:
  843.     case IG_STATE_PERS_ORTHO_TGL:
  844.     case IG_STATE_DEPTH_CUE:
  845.         WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  846.     default:
  847.         UpdateView = IGDefaultStateHandler(State, Refresh);
  848.         break;
  849.     }
  850.  
  851.     WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  852.     IGCreateStateMenu();
  853.  
  854.     return UpdateView;
  855. }
  856.  
  857. /*****************************************************************************
  858. * Routine to make some sound.                             *
  859. *****************************************************************************/
  860. void IGIritBeep(void)
  861. {
  862.     DosBeep(1000, 100);
  863. }
  864.